﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework;

namespace WindowsGame1
{
    class Ball2
    {
        public Vector2 RelPosition;                    // Position relative to collection.
        public int Budget;                      // Max number of alive particles.
        float NextSpawnIn;                      // This is a random number generated using the SecPerSpawn.
        float SecPassed;                        // Time pased since last spawn.

        public Vector2 SecPerSpawn;
        public Vector2 SpawnDirection;
        public Vector2 SpawnNoiseAngle;
        public Vector2 StartLife;
        public Vector2 StartScale;
        public Vector2 EndScale;
        public Color StartColor1;
        public Color StartColor2;
        public Color EndColor1;
        public Color EndColor2;
        public Vector2 StartSpeed;
        public Vector2 EndSpeed;


        public SpriteFont PausedFont;
        Player[] Platforms = new Player[4];
        int lastHit = 5;
        public int numPlayers;
        SpriteBatch spriteBatch;
        Texture2D particleBase;
        SoundEffect DeadSound;
        SoundEffect BounceSound;
        float ballRadius = 0.01875f;
        int Scale;
        public float Aspect;
        Vector2 position;
        public Vector2 Position
        {
            get { return position; }
            set { LastPos = position; position = value; }
        }
        public Vector2 LastPos;
        public Vector2 Direction;
        public bool Paused;
        float ResumeInSec;
        int aquiredSpeed = 0;
        Random random;

        public void Pause()
        {
            Paused = true;
            ResumeInSec = 1;
        }

        public Ball2(SpriteBatch spriteBatch, Texture2D particleBase, Vector2 WindowSize, Player[] Paddles, SoundEffect sound, SoundEffect sound2)
        {
            this.DeadSound = sound;
            this.BounceSound = sound2;
            for (int i = 0; i < Paddles.Length; i++)
            {
                this.Platforms[i] = Paddles[i];
            }
            this.spriteBatch = spriteBatch;
            this.particleBase = particleBase;
            this.Scale = (int)WindowSize.Y;
            random = new Random();

            this.SecPerSpawn = new Vector2(0.001f, 0.0015f);
            this.SpawnDirection = new Vector2(0, -1);
            this.SpawnNoiseAngle = new Vector2((float)(-0.128f * Math.PI*8), (float)(0.128f * Math.PI*8));
            this.StartLife = new Vector2(0.75f, 1.0f);
            this.StartScale = new Vector2(0.025f, 0.0375f);
            this.EndScale = new Vector2(0.0125f, 0.0180f);
            this.StartColor1 = Color.White;
            this.StartColor2 = Color.Black;
            this.EndColor1 = Color.Orange;
            this.EndColor2 = Color.Orange;
            this.StartSpeed = new Vector2(0.00f, 0.27f);
            this.EndSpeed = new Vector2(0.00f, 0.04f);
            this.random = random;
            this.NextSpawnIn = MathLib.LinearInterpolate(SecPerSpawn.X, SecPerSpawn.Y, random.NextDouble());
            this.SecPassed = 0.0f;
        
        }

        public void ReInitialize()
        {
            Position = new Vector2(0.5f * this.Aspect, 0.5f);
            Direction = new Vector2((float)random.NextDouble() - 0.5f, (float)(random.NextDouble() - 0.5f) / 1.5f);
            Direction.Normalize();
            if (Math.Abs(Direction.Y) > Math.Abs(Direction.X))
            {
                Direction.Y = Direction.X;
            }
            Direction.Normalize();
            aquiredSpeed = aquiredSpeed / 2;
            Direction *= 0.5f * (float)Math.Pow(1.05, aquiredSpeed);
            lastHit = 5;
        }

        public void Restart(int lives)
        {
            for (int i = 0; i < numPlayers; i++)
            {
                Platforms[i].Reset(lives);
            }
            ReInitialize();
            Paused = false;
        }

        public void Update(float dt)
        {
            if (!Paused)
            {
                Rectangle ballRect = new Rectangle((int)((Position.X - ballRadius) * Scale), (int)((Position.Y - ballRadius) * Scale), (int)(ballRadius * 2 * Scale), (int)(ballRadius * 2 * Scale));
                int i = 0;
                for (i = 0; i < numPlayers; i++)
                {
                    if (ballRect.Intersects(new Rectangle((int)(Platforms[i].Position.X * Scale), (int)(Platforms[i].Position.Y * Scale), (int)(Platforms[i].Size.X * Scale), (int)(Platforms[i].Size.Y * Scale))))
                    {
                        if (i == 0 || i == 1)
                        {
                            if (lastHit != i)
                            {
                                float speed = Direction.Length() * 1.1f;
                                aquiredSpeed++;
                                Direction.Normalize();
                                float distFromMiddle = (Platforms[i].Position.Y + Platforms[i].Size.Y / 2 - Position.Y) / Platforms[i].Size.Y;    // Negative is below, positive is above [-1, 1]
                                // The most rear adds 2 
                                BounceSound.Play();
                                Direction.Y += -2 * distFromMiddle;
                                Direction.X *= -1;
                                Direction.Normalize();
                                speed = MathHelper.Clamp(speed, 0, 3);
                                Direction *= speed;
                                lastHit = i;
                            }
                        }
                    }
                }
                if (numPlayers < 4)
                {
                    if (Position.Y < ballRadius || Position.Y > 1.0f - ballRadius)
                    {
                        Direction.Y *= -1;
                        BounceSound.Play();
                    }
                    else if (Position.X + ballRadius < 0)
                    {
                        Platforms[0].ReduceLife();
                        Pause();
                        this.ReInitialize();
                        DeadSound.Play();
                        return;
                    }
                    else if (Position.X - ballRadius > 1.0f * Aspect)
                    {
                        Platforms[1].ReduceLife();
                        Pause();
                        this.ReInitialize();
                        DeadSound.Play();
                        return;
                    }
                }
                Position += Direction * dt;

                Vector2 StartDirection = Vector2.Transform(SpawnDirection, Matrix.CreateRotationZ(MathLib.LinearInterpolate(SpawnNoiseAngle.X, SpawnNoiseAngle.Y, random.NextDouble())));
                StartDirection.Normalize();
                Vector2 EndDirection = StartDirection * MathLib.LinearInterpolate(EndSpeed.X, EndSpeed.Y, random.NextDouble());
                StartDirection *= MathLib.LinearInterpolate(StartSpeed.X, StartSpeed.Y, random.NextDouble());
                //Position += MathLib.LinearInterpolate(EndDirection, StartDirection, 1) * dt;
            }
            else
            {
                ResumeInSec -= dt;
                if (ResumeInSec < 0)
                {
                    Paused = false;
                }
            }
        }

        public void SetScale(int Scale)
        {
            this.Scale = Scale;
        }

        public void Draw(Vector2 Offset)
        {
            if (!Paused)
            {
                float currScale = 0.1f;
                spriteBatch.Draw(particleBase, new Rectangle((int)((Position.X - 0.5f * currScale) * Scale + Offset.X), (int)((Position.Y - 0.5f * currScale) * Scale + Offset.Y), (int)(currScale * Scale), (int)(currScale * Scale)), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0);
            }
            else
            {
                string timeleft = ResumeInSec.ToString();
                if (timeleft.Length > 3)
                {
                    timeleft = timeleft.Substring(0, 3);
                }
                spriteBatch.DrawString(PausedFont,
                "Kolejna szansa za " + timeleft + " sekund",
                new Vector2(0.5f * Aspect * Scale - PausedFont.MeasureString("Kolejna szansa za " + timeleft + " sekund").X / 2, 0.4f * Scale),
                    Color.White);
            }
        }
    }
}
